<?php
class app extends abstract_app {

    protected $app_path;
    protected $view_path;
    protected $theme;

    public function __construct($registry, $config) {
        parent::__construct($registry, $config);

        // Get Id
        $config->set_section('app');
        $this->id = $config->get('id');

        // Setup Paths
        $this->view_path = $this->get_path('dir_template');
        $this->app_path = $this->get_path('dir_app');

        // Setup Theme
        $config->set_section('config');
        $this->theme = $config->get('theme');

        // Setup Actions 
        $config->set_section('actions');

        // Set Default Action
        $this->action       = $this->action($config->get('default'));

        // Set Error action 
        $this->error_action = $this->action($config->get('error'));

        // Setup Pre Actions
        $config->set_section('pre_actions');
        $pre_action   = $config->get_all(); 
        foreach ($pre_action as $pre_action) {
            $this->pre_action[] = $this->action($pre_action);
        }

    }

    public function action($route, $args = array()) {
        
        $file = null;
        $class = null;
        $method = null;

        $path = '';	
        $parts = explode('/', str_replace('../', '', (string)$route));

        foreach ($parts as $part) { 
            $path .= $part;

            if (is_dir($this->app_path . 'controller/' . $path)) {
                $path .= '/';

                array_shift($parts);

                continue;
            }

            if (is_file($this->app_path . 'controller/' . str_replace(array('../', '..\\', '..'), '', $path) . '.php')) {
                $file = $this->app_path . 'controller/' . str_replace(array('../', '..\\', '..'), '', $path) . '.php';

                $class = 'Controller' . preg_replace('/[^a-zA-Z0-9]/', '', $path);

                array_shift($parts);

                break;
            }
        }

        $method = array_shift($parts);

        if ($method) {
            $method = $method;
        } else {
            $method = 'index';
        }

        return new Action($file, $class, $method, $args); 
    }

	public function resource($action) {
			
		if(!($action instanceof action)) {
			throw new Exception('Invalid Action');
		}		

		$classname = $action->get_classname();
		if(class_exists($classname, false)) {	
			return $classname;
		}
		
		$filename = $action->get_filename();		
		if(!file_exists($filename)){
			throw new Exception('Could not load file: "' . $filename . '" !');
		}
		include_once($filename);
			
		if(!class_exists($classname, false)) {		
			throw new Exception('Could not load Class: "' . $classname . '" on File: "'.$filename.'" !');
		}
		
		return $classname;
	}


    public function controller(interface_action $action, $execute = false) {

        $classname = $this->resource($action);

        $controller = new $classname($this->registry, $this);

        if(!$execute) {
            return $controller;
        }

        $method = $action->get_method();
        $args   = $action->get_args();

        if (is_callable(array($controller, $method))) {
            return $controller->{$method}($args);
        }

        throw new Exception('Could not call controller method: ' . $classname . '::' . $method);
    }

    public function model($model, $instantiate = false, $global = false) {

        $classname = 'model_' . str_replace('/', '_', $model);
        $class = 'Model' . preg_replace('/[^a-zA-Z0-9]/', '', $model);
        $filename  = $this->app_path . 'model/' . $model . '.php';

        $action = new Action($filename, $class);
        $this->resource($action); 

        if($instantiate){

            $object = new $class($this->registry);

            if($global){
                $this->registry->set($classname, $object);
                return $class;
            }

            return $object;
        }

        return true;

    }
    
    public function view($template){

        if(is_dir($this->view_path . $this->theme . '/template/')){
            $path = $this->view_path . $this->theme . '/template/';
        } else {
            $path = $this->view_path . 'template/';
        }

        return new view($path . $template); 
    }

    public function language($directory, $default = 'english') {
        return new Language($this->get_path('dir_language'), $directory, $default);
    }
}
